﻿/************************************************************************

	File:			args.c
	Version:		1.0
	Changes:		A
	Author:			Stanley Lau
	Date:			2010.07.30
	Purpose:		Arguments process functions implement

************************************************************************/

#include "args.h"

PKArgs_a GetArgs_a( int argn, char** argv )
{
	int		bResult = 0;
	PKArgs_a	pArgs = NULL;

	if( argn <= 0 || NULL==argv )
		goto Exit0;

	pArgs = (PKArgs_a)calloc( 1, sizeof(KArgs_a) );
	if( !pArgs )
		goto Exit0;

	pArgs->pArgItem = (PKArgItem_a)calloc( argn, sizeof(KArgItem_a) );
	if( !pArgs->pArgItem )
		goto Exit0;
	pArgs->nArgItemCount = argn;

	if( !ParseArgs_a( pArgs, argn, argv ) )
		goto Exit0;

	bResult = 1;
Exit0:
	if( 0 == bResult )
	{
		if( pArgs )
			ReleaseArgs_a( pArgs );
		pArgs = NULL;
	}
	return pArgs;
}

int ReleaseArgs_a( PKArgs_a pArgs )
{
	int		bResult = 0;
	size_t	i = 0;

	if( !pArgs )
		goto Exit0;

	for( i = 0; i < pArgs->nArgItemCount; i++ )
	{
		if( pArgs->pArgItem[i].pstrItem )
			free( pArgs->pArgItem[i].pstrItem );
		if( pArgs->pArgItem[i].pstrItemName )
			free( pArgs->pArgItem[i].pstrItemName );
		if( pArgs->pArgItem[i].pstrItemValue )
			free( pArgs->pArgItem[i].pstrItemValue );
	}
	free( pArgs->pArgItem );
	free( pArgs );

	bResult = 1;
Exit0:
	return bResult;
}

int ParseArgs_a( PKArgs_a pArgs, int argn, char** argv )
{
	int		bResult = 0;
	int		i = 0;

	if( !pArgs || argn <= 0 || !argv || pArgs->nArgItemCount != argn )
		goto Exit0;

	for( i = 0; i < argn; i++ )
	{
		size_t	nArgLen = 0;
		char*	pstrStart = NULL, *pstrEnd = NULL;
		char*	pstrTemp = NULL;

		nArgLen = strlen( argv[i] );
		pstrTemp = (char*)malloc( sizeof(char) * (nArgLen + 1) );
		if( pstrTemp )
		{
			strcpy( pstrTemp, argv[i] );
			pArgs->pArgItem[i].pstrItem = pstrTemp;
		}

		if( nArgLen < MIN_ARG_LEN )
			continue;
		if( strncmp( argv[i], ARG_PREFIX_a, strlen(ARG_PREFIX_a) ) )
			continue;

		//Find item name and value
		pstrStart = argv[i] + strlen( ARG_PREFIX_a );
		pstrEnd = strstr( pstrStart, ARG_DELIMI_a );
		if( pstrEnd )
		{
			size_t nNameLen  = 0, nValueLen = 0;

			nNameLen = pstrEnd - pstrStart;
			if( nNameLen > 0 )
			{
				pstrTemp = (char*)malloc( sizeof(char) * (nNameLen + 1) );
				if( pstrTemp )
					strncpy( pstrTemp, pstrStart, nNameLen );
				pstrTemp[nNameLen] = 0;
				pArgs->pArgItem[i].pstrItemName = pstrTemp;
			}
			else
				pArgs->pArgItem[i].pstrItemName = NULL;

			pstrEnd += strlen( ARG_DELIMI_a );
			nValueLen = strlen( pstrStart );
			if( nValueLen > 0 )
			{
				pstrTemp = (char*)malloc( sizeof(char) * (nValueLen + 1) );
				if( pstrTemp )
					strcpy( pstrTemp, pstrEnd );
				pArgs->pArgItem[i].pstrItemValue = pstrTemp;
			}
			else
				pArgs->pArgItem[i].pstrItemValue = NULL;
		}
		else
		{
			size_t nNameLen = 0;
			nNameLen = strlen( pstrStart );
			pstrTemp = (char*)malloc( sizeof(char) * ( nNameLen + 1 ) );
			if( pstrTemp )
			{
				strcpy( pstrTemp, pstrStart );
			}
			pArgs->pArgItem[i].pstrItemName = pstrTemp;
			pArgs->pArgItem[i].pstrItemValue = NULL;
		}
	}

	bResult = 1;
Exit0:
	return bResult;
}


const char*	GetStringItem_a( PKArgs_a pArgs, const char* pstrName )
{
	char*		pstrValue = NULL;
	PKArgItem_a	pArgItem = NULL;

	pArgItem = FindItem_a( pArgs, pstrName );
	if( !pArgItem )
		goto Exit0;

	pstrValue = pArgItem->pstrItemValue;
Exit0:
	return pstrValue;
}
int GetIntItem_a( PKArgs_a pArgs, const char* pstrName )
{
	char*		pstrValue = NULL;
	int			nValue = 0;
	PKArgItem_a	pArgItem = NULL;

	pArgItem = FindItem_a( pArgs, pstrName );
	if( !pArgItem )
		goto Exit0;

	nValue = atoi( pArgItem->pstrItemValue ? pArgItem->pstrItemValue : 0 );
Exit0:
	return nValue;
}

PKArgItem_a FindItem_a( PKArgs_a pArgs, const char* pstrName )
{
	unsigned int	i = 0;
	PKArgItem_a		pArgItem = NULL;

	if( !pArgs || !pArgs->pArgItem || !pstrName )
		goto Exit0;

	for( i = 0; i < pArgs->nArgItemCount; i++ )
	{
		if( pArgs->pArgItem[i].pstrItemName && 0==strcmp( pArgs->pArgItem[i].pstrItemName, pstrName ) )
		{
			pArgItem = &pArgs->pArgItem[i];
			break;
		}
	}

Exit0:
	return pArgItem;
}

int HasItem_a( PKArgs_a pArgs, const char* pstrName )
{
	int			bHas = 0;
	PKArgItem_a	pArgItem = NULL;

	if( !pArgs || !pstrName )
		goto Exit0;

	pArgItem = FindItem_a( pArgs, pstrName );
	bHas = pArgItem ? 1 : 0;
Exit0:
	return bHas;
}




PKArgs_w GetArgs_w( int argn, wchar_t** argv )
{
	int		bResult = 0;
	PKArgs_w	pArgs = NULL;

	if( argn <= 0 || NULL==argv )
		goto Exit0;

	pArgs = (PKArgs_w)calloc( 1, sizeof(KArgs_a) );
	if( !pArgs )
		goto Exit0;

	pArgs->pArgItem = (PKArgItem_w)calloc( argn, sizeof(KArgItem_w) );
	if( !pArgs->pArgItem )
		goto Exit0;
	pArgs->nArgItemCount = argn;

	if( !ParseArgs_w( pArgs, argn, argv ) )
		goto Exit0;

	bResult = 1;
Exit0:
	if( 0 == bResult )
	{
		if( pArgs )
			ReleaseArgs_w( pArgs );
		pArgs = NULL;
	}
	return pArgs;
}

int ReleaseArgs_w( PKArgs_w pArgs )
{
	int		bResult = 0;
	size_t	i = 0;

	if( !pArgs )
		goto Exit0;

	for( i = 0; i < pArgs->nArgItemCount; i++ )
	{
		if( pArgs->pArgItem[i].pstrItem )
			free( pArgs->pArgItem[i].pstrItem );
		if( pArgs->pArgItem[i].pstrItemName )
			free( pArgs->pArgItem[i].pstrItemName );
		if( pArgs->pArgItem[i].pstrItemValue )
			free( pArgs->pArgItem[i].pstrItemValue );
	}
	free( pArgs->pArgItem );
	free( pArgs );

	bResult = 1;
Exit0:
	return bResult;
}

int ParseArgs_w( PKArgs_w pArgs, int argn, wchar_t** argv )
{
	int		bResult = 0;
	int		i = 0;

	if( !pArgs || argn <= 0 || !argv || pArgs->nArgItemCount != argn )
		goto Exit0;

	for( i = 0; i < argn; i++ )
	{
		size_t	nArgLen = 0;
		wchar_t*	pstrStart = NULL, *pstrEnd = NULL;
		wchar_t*	pstrTemp = NULL;

		nArgLen = wcslen( argv[i] );
		pstrTemp = (wchar_t*)malloc( sizeof(wchar_t) * (nArgLen + 1) );
		if( pstrTemp )
		{
			wcscpy( pstrTemp, argv[i] );
			pArgs->pArgItem[i].pstrItem = pstrTemp;
		}

		if( nArgLen < MIN_ARG_LEN )
			continue;
		if( wcsncmp( argv[i], ARG_PREFIX_w, wcslen(ARG_PREFIX_w) ) )
			continue;

		//Find item name and value
		pstrStart = argv[i] + wcslen( ARG_PREFIX_w );
		pstrEnd = wcsstr( pstrStart, ARG_DELIMI_w );
		if( pstrEnd )
		{
			size_t nNameLen  = 0, nValueLen = 0;

			nNameLen = pstrEnd - pstrStart;
			if( nNameLen > 0 )
			{
				pstrTemp = (wchar_t*)malloc( sizeof(wchar_t) * (nNameLen + 1) );
				if( pstrTemp )
					wcsncpy( pstrTemp, pstrStart, nNameLen );
				pstrTemp[nNameLen] = 0;
				pArgs->pArgItem[i].pstrItemName = pstrTemp;
			}
			else
				pArgs->pArgItem[i].pstrItemName = NULL;

			pstrEnd += wcslen( ARG_DELIMI_w );
			nValueLen = wcslen( pstrStart );
			if( nValueLen > 0 )
			{
				pstrTemp = (wchar_t*)malloc( sizeof(wchar_t) * (nValueLen + 1) );
				if( pstrTemp )
					wcscpy( pstrTemp, pstrEnd );
				pArgs->pArgItem[i].pstrItemValue = pstrTemp;
			}
			else
				pArgs->pArgItem[i].pstrItemValue = NULL;
		}
		else
		{
			size_t nNameLen = 0;
			nNameLen = wcslen( pstrStart );
			pstrTemp = (wchar_t*)malloc( sizeof(wchar_t) * ( nNameLen + 1 ) );
			if( pstrTemp )
			{
				wcscpy( pstrTemp, pstrStart );
			}
			pArgs->pArgItem[i].pstrItemName = pstrTemp;
			pArgs->pArgItem[i].pstrItemValue = NULL;
		}
	}

	bResult = 1;
Exit0:
	return bResult;
}


const wchar_t*	GetStringItem_w( PKArgs_w pArgs, const wchar_t* pstrName )
{
	wchar_t*	pstrValue = NULL;
	PKArgItem_w	pArgItem = NULL;

	pArgItem = FindItem_w( pArgs, pstrName );
	if( !pArgItem )
		goto Exit0;

	pstrValue = pArgItem->pstrItemValue;
Exit0:
	return pstrValue;
}
int GetIntItem_w( PKArgs_w pArgs, const wchar_t* pstrName )
{
	wchar_t*		pstrValue = NULL;
	int			nValue = 0;
	PKArgItem_w	pArgItem = NULL;

	pArgItem = FindItem_w( pArgs, pstrName );
	if( !pArgItem )
		goto Exit0;

	nValue = _wtoi( pArgItem->pstrItemValue ? pArgItem->pstrItemValue : 0 );
Exit0:
	return nValue;
}

PKArgItem_w FindItem_w( PKArgs_w pArgs, const wchar_t* pstrName )
{
	unsigned int	i = 0;
	PKArgItem_w		pArgItem = NULL;

	if( !pArgs || !pArgs->pArgItem || !pstrName )
		goto Exit0;

	for( i = 0; i < pArgs->nArgItemCount; i++ )
	{
		if( pArgs->pArgItem[i].pstrItemName && 0==wcscmp( pArgs->pArgItem[i].pstrItemName, pstrName ) )
		{
			pArgItem = &pArgs->pArgItem[i];
			break;
		}
	}

Exit0:
	return pArgItem;
}

int HasItem_w( PKArgs_w pArgs, const wchar_t* pstrName )
{
	int bHas = 0;
	PKArgItem_w pArgItem = NULL;

	if( !pArgs || !pstrName )
		goto Exit0;

	pArgItem = FindItem_w( pArgs, pstrName );
	bHas = pArgItem ? 1 : 0;
Exit0:
	return bHas;
}
//Last line for linux

